import Koa from 'koa'
import consola from 'consola'
import { Nuxt, Builder } from 'nuxt'

import bodyParser from 'koa-bodyparser'
import json from 'koa-json'
import session from 'koa-generic-session'

import { connectMongodb, getRedisConnect } from './db/init'
import passport from './util/passport'
import userRoute from './interface/user'
import geoRoute from './interface/geo'
import searchRoute from './interface/search'
import categoryRouter from './interface/category'

const app = new Koa()
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 3000

connectMongodb()

app.keys = ['mt', 'keyskeys']
app.proxy = true
app.use(session({ key: 'mt', prefix: 'mt:uid', store: getRedisConnect() }))
app.use(bodyParser({ extendTypes: ['json', 'form', 'text'] }))
app.use(json())
app.use(passport.initialize())
app.use(passport.session())

// Import and Set Nuxt.js options
import config from '../nuxt.config.js'

config.dev = !(app.env === 'production')

async function start() {
  // Instantiate nuxt.js
  const nuxt = new Nuxt(config)

  // Build in development
  if (config.dev) {
    const builder = new Builder(nuxt)
    await builder.build()
  }
  app.use(userRoute.routes()).use(userRoute.allowedMethods())
  app.use(geoRoute.routes()).use(geoRoute.allowedMethods())
  app.use(searchRoute.routes()).use(searchRoute.allowedMethods())
  app.use(categoryRouter.routes()).use(categoryRouter.allowedMethods())
  app.use(ctx => {
    ctx.status = 200 // koa defaults to 404 when it sees that status is unset

    return new Promise((resolve, reject) => {
      ctx.res.on('close', resolve)
      ctx.res.on('finish', resolve)
      nuxt.render(ctx.req, ctx.res, promise => {
        // nuxt.render passes a rejected promise into callback on error.
        promise.then(resolve).catch(reject)
      })
    })
  })

  app.listen(port, host)
  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  })
}

start()
